package com.iplant.wms.serviceImpl.dao.mrp;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.enums.DBSchemas;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.annotation.dao.DBBaseDAO;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.BaseDAO;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.wms.service.basicenum.wms.WMSStockRecordType;
import com.iplant.wms.service.po.mrp.MRPDelivery;
import com.iplant.wms.service.po.mrp.MRPDeliveryItem;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

@DBBaseDAO(MRPDelivery.class)
@Slf4j
public class MRPDeliveryDAO extends BaseDAO {

    private static MRPDeliveryDAO Instance = null;

    public static MRPDeliveryDAO getInstance() {
        if (Instance == null) {
            Instance = new MRPDeliveryDAO();
        }
        return Instance;
    }

    public MRPDeliveryDAO() {
        super("");
        this.Init();
    }


    public void MRP_UpdateDelivery(BMSEmployee wLoginUser, MRPDelivery wMRPDelivery, OutResult<Integer> wErrorCode) {

        this.UpdatePo(wLoginUser, wMRPDelivery, wErrorCode);
        if (wErrorCode.Result != 0 || wMRPDelivery.ItemList == null)
            return;
        for (MRPDeliveryItem mrpMaterialItem : wMRPDelivery.ItemList) {
            mrpMaterialItem.DeliveryID = wMRPDelivery.ID;
        }
        MRPDeliveryItemDAO.getInstance().UpdatePoList(wLoginUser, wMRPDelivery.ItemList, wErrorCode);
    }

    public void MRP_DeleteDeliveryByIDList(BMSEmployee wLoginUser, List<Integer> wIDList, OutResult<Integer> wErrorCode) {
        if (wIDList == null || wIDList.size() == 0)
            return;
        Map<String, Object> wData = new HashMap<>();

        wData.put("Active", 2);
        wData.put("PlanFQTY", 0);

        this.Update(wData, null, StringUtils.Format(" AND ID IN ({0})", StringUtils.Join(",", wIDList)));


        wData.put("FQTYDone", 0);
        this.Delete(wData, StringUtils.Format("AND ID IN ({0})", StringUtils.Join(",", wIDList)));

    }

    public void MRP_DeleteDeliveryList(BMSEmployee wLoginUser, List<MRPDelivery> wMRPDeliveryList, OutResult<Integer> wErrorCode) {

        List<Integer> wDeletePlanIDList = new ArrayList();
        for (MRPDelivery mrpDelivery : wMRPDeliveryList) {
            wDeletePlanIDList.add(mrpDelivery.ID);
        }
        MRPDeliveryDAO.getInstance().MRP_DeleteDeliveryByIDList(wLoginUser, wDeletePlanIDList, wErrorCode);
        if (wErrorCode.Result != 0)
            return;
        MRPDeliveryItemDAO.getInstance().MRP_DeleteDeliveryItemByPlanIDList(wLoginUser, wDeletePlanIDList, wErrorCode);
    }


    public List<MRPDelivery> MRP_SelectDeliveryListByDate(BMSEmployee wLoginUser,
                                                          Calendar wStartDate, Calendar wEndDate, Pagination wPagination, OutResult<Integer> wErrorCode) {
        Map<String, Object> wParams = new HashMap<>();
        wParams.put("StartDate", wStartDate);
        wParams.put("EndDate", wEndDate);

        List<MRPDelivery> wResult = this.SelectPOList(wLoginUser, wParams, wPagination, wErrorCode);


        return wResult;
    }


    /**
     * 自动更新配料数  和荣专属
     *
     * @param wLoginUser
     * @param wStartDate
     * @param wEndDate
     * @param wErrorCode
     */
    public void MRP_UpdateDeliveryFQTYDone(BMSEmployee wLoginUser, Calendar wStartDate, Calendar wEndDate, OutResult<Integer> wErrorCode) {
        try {
            if (wStartDate == null || wEndDate == null)
                return;

            wStartDate = CalendarTool.getDate(wStartDate);
            wEndDate = CalendarTool.getDate(wEndDate);
            wEndDate.add(Calendar.DAY_OF_MONTH, 1);
            String wSQLText = StringUtils.Format("update {0} t set t.FQTYDone= " +
                            "( select ifnull( sum(t2.ReceiveQuantity),0) from {1} t2 WHERE t2.FactoryID=t.FactoryID" +
                            " and t.OrderNo=t2.ProjectNo and t.MaterialID=t2.MaterialID  " +
                            " and DATE_FORMAT(t2.CreateTime, ''%Y-%m-01'') = DATE_FORMAT(t.DemandDate, ''%Y-%m-01'') )" +
                            " where  t.ID>0 and t.DemandDate>= :wStartDate and t.DemandDate< :wEndDate   ",
                    this.getTableName(), this.getTableName(DBSchemas.WMS, "wms_receivebillitem"));

            Map<String, Object> wParams = new HashMap<>();
            wParams.put("wStartDate", wStartDate);
            wParams.put("wEndDate", wEndDate);
            this.Update(wSQLText, wParams);

            MRPDeliveryItemDAO.getInstance().WMS_UpdateDeliveryItemItemFQTY(wLoginUser, wStartDate, wEndDate, wErrorCode);
        } catch (Exception e) {
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
            log.error("MRP_UpdateDeliveryFQTYDone", e);
        }
    }

    /**
     * 自动更新使用数 交接调用   和荣专属
     *
     * @param wLoginUser
     * @param wStartDate
     * @param wEndDate
     * @param wErrorCode
     */
    public void MRP_UpdateDeliveryFQTYUsed(BMSEmployee wLoginUser, Calendar wStartDate, Calendar wEndDate, OutResult<Integer> wErrorCode) {
        try {


            if (wStartDate == null || wEndDate == null)
                return;

            wStartDate = CalendarTool.getDate(wStartDate);
            wEndDate = CalendarTool.getDate(wEndDate);
            wEndDate.add(Calendar.DAY_OF_MONTH, 1);
            String wSQLText = StringUtils.Format("update {0} t set t.FQTYUsed= " +
                            "( select ifnull( sum(t2.OutboundQuantity),0) from {1} t2" +
                            " inner join {2} t3 on t2.OutboundOrderID=t3.ID WHERE t2.FactoryID=t.FactoryID" +
                            " and t.OrderNo=t2.ProjectNo and t.MaterialID=t2.MaterialID " +
                            " and t3.Type=:wOutboundOrderType and t2.StockRecordID>0 and t2.StockOperateRecordID>0 " +
                            " and t2.OutboundQuantity>0 and t2.StoreStationID>0  " +
                            " and DATE_FORMAT(t2.CreateTime, ''%Y-%m-01'') = DATE_FORMAT(t.DemandDate, ''%Y-%m-01'') )" +
                            " where  t.ID>0 and t.DemandDate>= :wStartDate and t.DemandDate< :wEndDate   ",
                    this.getTableName(), this.getTableName(DBSchemas.WMS, "wms_outboundorderitem")
                    , this.getTableName("wms_outbound_order"));

            Map<String, Object> wParams = new HashMap<>();
            wParams.put("wStartDate", wStartDate);
            wParams.put("wEndDate", wEndDate);
            wParams.put("wOutboundOrderType", WMSStockRecordType.ProductionOutOfStock.getValue());
            this.Update(wSQLText, wParams);


        } catch (Exception e) {
            wErrorCode.Result = ExceptionTypes.DBSQL.getValue();
            log.error("MRP_UpdateDeliveryFQTYDone", e);
        }
    }

}
